|
Writing custom report components
FastReport has a great number of components, which can be placed into a report page. They are: text, picture, line, geometrical figure, OLE, Rich, bar code, diagram etc. You can also write your own component, and then attach it to FastReport. In FastReport, there are several defined classes, from which the components are inherited. For more details, see the “Hierarchy of classes” chapter. The TfrxView class is of main interest to us, since most report components are inherited from it. One should realize at least the “Draw” method defined in the TfrxReportComponent basic class. procedure Draw(Canvas: TCanvas; ScaleX, ScaleY, OffsetX, OffsetY:Extended); virtual ; This method is called when a component is painted, in the designer, in the preview window, and during printing. The TfrxView overrides this method for drawing object’s frame and background. The method should draw the component’s contents on the “Canvas” drawing surface. Object’s coordinates and sizes are stored in the “AbsLeft, AbsTop,” “Width,” and “Height” properties respectively. The “ScaleX” and “ScaleY” parameters define scaling of an object in X-axis and Y-axis respectively. These parameters are equal 1 at 100% zoom and can vary, if a user modifies zooming either in the designer or in the preview window. The OffsetX and OffsetY parameters point shifting of the coordinates by the X-axis and Y-axis. Thus, taking into account these parameters, a coordinate of the upper left corner will be as following: X := Round(AbsLeft * ScaleX + OffsetX); To simplify operations with coordinates, the “BeginDraw” method (which has parameters similar to the “Draw” method) is defined in the “TfrxView” class procedure BeginDraw(Canvas: TCanvas; ScaleX, ScaleY, OffsetX, OffsetY:Extended); virtual ; It should be called in the first line of the “Draw” method. This method performs transformation of the coordinates into FX, FY, FX1, FY1, FDX, FDY, FFrameWidth integer values, which can be later used in the TCanvas methods. This method also copies the Canvas, ScaleX, and ScaleY values into the FCanvas, FScaleX, FScaleY variables to which one can refer from any method of the class. There are also two methods for drawing backgrounds for and frames of objects in the TfrxView class. procedure DrawBackground; procedure DrawFrame; The BeginDraw method should be called before calling these methods. Let us examine creation process of the component, which displays an arrow. type public procedure Draw(Canvas: TCanvas; ScaleX, ScaleY, OffsetX, OffsetY: Extended); override ; class function GetDescription: String ; override ; published property BrushStyle; property Color; property Frame; end ; class function TfrxArrowView.GetDescription: String ; begin Result := 'Arrow object'; end ; procedure TfrxArrowView.Draw(Canvas: TCanvas; ScaleX, ScaleY, OffsetX, OffsetY: Extended); begin BeginDraw(Canvas, ScaleX, ScaleY, OffsetX, OffsetY); with Canvas do begin Brush.Color := Color; Brush.Style := BrushStyle; Pen.Width := FFrameWidth; Pen.Color := Frame.Color; { draw an arrow } Polygon( Point(FX + FDX * 38 div 60, FY + FDY div 4), Point(FX + FDX * 38 div 60, FY), Point(FX1, FY + FDY div 2), Point(FX + FDX * 38 div 60, FY1), Point(FX + FDX * 38 div 60, FY + FDY * 3 div 4), Point(FX, FY + FDY * 3 div 4)]); end; end; { registration } var initialization Bmp.LoadFromResourceName(hInstance, 'frxArrowView'); { place our component to the “Other” standard category } frxObjects.RegisterObject(TfrxArrowView, Bmp, 'Other'); finalization frxObjects.Unregister(TfrxArrowView); Bmp.Free; end. To create a component, which displays any data from DB, one should transfer the DataSet, DataField properties into the “published” section, and then override the “GetData” method. Let us examine it on the example of the TfrxCheckBoxView standard component. The component can be connected to DB field via the “DataSet” and “DataField” properties, which are presented in the TfrxView basic class. In addition, this component has the “Expression” property, into which an expression can be placed. As soon as it is calculated, the result will be placed into the “Checked” property. The component displays a check, if the “Checked” property equals “True.” Below is the initial text (the most important parts of it) of this component. TfrxCheckBoxView = class (TfrxView) private FExpression: String ; procedure DrawCheck(ARect: TRect); public procedure GetData; override ; published property DataField; property DataSet; property Expression: String read FExpression write FExpression; end; procedure TfrxCheckBoxView.Draw(Canvas: TCanvas; ScaleX, ScaleY, OffsetX, OffsetY: Extended); begin DrawBackground; DrawCheck(Rect(FX, FY, FX1, FY1)); DrawFrame; end; procedureTfrxCheckBoxView.GetData; begin if IsDataField then else if FExpression <> '' then end; |